﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using Ast.Framework.Caching;
using Ast.Framework.FileSystems.Paths;
using Castle.Core.Logging;

namespace Ast.Framework.FileSystems.SiteFolders
{
    public class SiteFolder : ISiteFolder
    {
        private readonly IPathProvider _pathProvider;
        private readonly IPathMonitor _pathMonitor;

        public SiteFolder(IPathMonitor pathMonitor, IPathProvider pathProvider)
        {
            _pathMonitor = pathMonitor;
            _pathProvider = pathProvider;

            Logger = NullLogger.Instance;
        }

        public ILogger Logger { get; set; }

        public IEnumerable<string> ListDirectories(string path)
        {
            if (!_pathProvider.DirectoryExists(path))
            {
                return Enumerable.Empty<string>();
            }

            return _pathProvider.ListDirectories(path);
        }

        private IEnumerable<string> ListFiles(IEnumerable<string> directories)
        {
            return directories.SelectMany(d => ListFiles(d, true));
        }

        public IEnumerable<string> ListFiles(string path, bool recursive)
        {
            if (!recursive)
            {
                return _pathProvider.ListFiles(path);
            }
            return _pathProvider.ListFiles(path).Concat(ListFiles(ListDirectories(path)));
        }

        public bool FileExists(string path)
        {
            return _pathProvider.FileExists(path);
        }

        public string ReadFile(string path)
        {
            using (var stream = _pathProvider.OpenFile(path))
            {
                using (var reader = new StreamReader(stream))
                {
                    return reader.ReadToEnd();
                }
            }
        }

        public void CopyFileTo(string path, Stream destination)
        {
            using (var stream = _pathProvider.OpenFile(path))
            {
                stream.CopyTo(destination);
            }
        }

        public IVolatileToken WhenPathChanges(string path)
        {
            return _pathMonitor.WhenPathChanges(path);
        }
    }
}